#ifndef __TEST_H__
#define __TEST_H__

#include <iostream>
#include <string_view>
#include <functional>

namespace test
{
    // 传统紧耦合方式
    void deliverFood()
    {
        std::cout << "📌咚咚咚！您的外卖到了！" << std::endl;
        // 需要知道具体通知方式
    }

    // 回调解耦方式
    using NotifyCallback = void (*)(); // 📌关键函数指针类型定义

    void deliveryService(NotifyCallback callback)
    {
        // 处理配送流程...
        callback(); // 🚀 神奇的回调触发点
    }

    void myNotification()
    {
        std::cout << "📱【美团】您的外卖已到达小区门口" << std::endl;
    }

    // 赋值：合法函数地址
    int add(int a, int b) { return a + b; }

    class Downloader
    {
    public:
        using ProgressCallback = void (*)(int);
        using CompleteCallback = void (*)(std::string_view);

        Downloader(ProgressCallback pc, CompleteCallback cc)
            : progressCb(pc),
              completeCb(cc)
        {
        }

        void start()
        {
            for (int i = 0; i <= 100; i += 10)
            {
                progressCb(i); // 📈 进度通知
            }

            completeCb("/data/file.zip"); // 🎉 完成通知
        }

    private:
        ProgressCallback progressCb;
        CompleteCallback completeCb;
    };

    // 业务层自由组合回调
    void showProgress(int p)
    {
        std::cout << "下载进度：" << p << "%" << std::endl;
    }

    void saveToDB(std::string_view path)
    {
        std::cout << "下载完成：" << path << std::endl;
    }

    class Functional
    {
    public:
        void setCallFunc(std::function<void(int)> func)
        {
            m_func = func;
        }

        void statr()
        {
            m_func(100);
        }

    private:
        std::function<void(int)> m_func;
    };

    void test()
    {
        // deliveryService(deliverFood);    // 💉 注入自定义逻辑
        // deliveryService(myNotification); // 💉 注入自定义逻辑

        // // 调用：像普通函数一样使用
        // // 声明：返回类型 (*指针名)(参数列表)
        // int (*mathFunc)(int, int);
        // mathFunc = &add; // 或 mathFunc = add;

        // std::cout << mathFunc(3, 5) << std::endl; // 输出8

        // 函数指针
        // Downloader dl(showProgress, saveToDB);
        // dl.start();

        // std::function 使用
        Functional func;
        func.setCallFunc([](int progress)
                         { std::cout << progress << std::endl; });
        func.statr();
    }
}

#endif